import re
from django.conf import settings
from django_redis import get_redis_connection
from rest_framework import serializers
from itsdangerous import TimedJSONWebSignatureSerializer  as TJS
from rest_framework_jwt.settings import api_settings

from oauth.models import OAuthQQUser
from users.models import User


class QQAuthUserSerializer(serializers.ModelSerializer):
    # 显示指明user中木有的字段
    sms_code = serializers.CharField(max_length=6, min_length=6, write_only=True)
    openid = serializers.CharField(write_only=True)
    token = serializers.CharField(read_only=True)
    user_id = serializers.IntegerField(read_only=True)

    mobile = serializers.CharField(max_length=11)

    class Meta:
        model = User
        fields = ('mobile', 'password', 'sms_code', 'openid', 'username', 'token', 'user_id', 'id')
        extra_kwargs = {
            'password': {
                'write_only': True,
                'max_length': 20,
                'min_length': 8,
                'error_messages': {
                    'max_length': '密码过长'
                }
            },
            'username': {
                'read_only': True,
                'max_length': 20,
                'min_length': 5,
                'error_messages': {
                    'max_length': '名字过长',
                    'min_length': '名字过短'
                }
            },
        }

    # 手机号验证
    def validate_mobile(self, value):
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机格式不正确')

        return value

    def validate(self, attrs):

        # 验证openid
        tjs = TJS(settings.SECRET_KEY, 300)
        # 解密
        try:
            data = tjs.loads(attrs['openid'])
        except:
            raise serializers.ValidationError('openid错误')

        openid = data.get('openid')
        # attrs中没有解密后oepnid 需要进行添加
        attrs['open_id'] = openid

        # 验证短信验证码
        # 建立缓存redis连接
        conn = get_redis_connection('verify')

        # 取出真实验证码   bytes
        real_sms = conn.get('sms_%s' % attrs['mobile'])

        # 判断是否能取出值
        if not real_sms:
            raise serializers.ValidationError('短信验证码已过期')

        # 验证码比对
        if attrs['sms_code'] != real_sms.decode():
            raise serializers.ValidationError('短信验证码不一致')

        # 验证用户是否注册过
        try:
            user = User.objects.get(mobile=attrs['mobile'])
        except:
            # 用户未注册
            return attrs
        else:
            # 用户已注册
            # 密码校验
            if not user.check_password(attrs['password']):
                raise serializers.ValidationError('密码错误')

            attrs['user'] = user
            return attrs

    def create(self, validated_data):
        # 获取用户对象
        user = validated_data.get('user', None)

        # 判断用户是否注册
        if user is None:
            user = User.objects.create_user(username=validated_data['mobile'], password=validated_data['password'],
                                            mobile=validated_data['mobile'])

        OAuthQQUser.objects.create(user=user, openid=validated_data['open_id'])

        # 生成token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 用户对象额外添加token属性
        user.token = token
        user.user_id = user.id

        return user
